package com.mlethe.library.dialog;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Build;
import android.os.Bundle;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.annotation.DrawableRes;
import androidx.annotation.IdRes;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Px;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentManager;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;

/**
 * 自定义DialogFragment
 * 解决DialogFragment的内存泄漏
 *
 * @author Mlethe
 * @date 2020/8/4
 */
public abstract class DialogFragment extends androidx.fragment.app.DialogFragment {

    private static final String SAVED_DIALOG_STATE_TAG = "android:savedDialogState";
    private static final String SAVED_DIALOG_STATE = "android:dialogState";
    private static final String SAVED_CANCELABLE = "android:cancelable";
    private static final String SAVED_CANCELABLE_OUTSIDE = "android:cancelableOnTouchOutside";
    private static final String SAVED_DIALOG_WIDTH = "android:dialogWidth";
    private static final String SAVED_DIALOG_HEIGHT = "android:dialogHeight";
    private static final String SAVED_DIALOG_GRAVITY = "android:dialogGravity";
    private static final String SAVED_DIALOG_LOCATION_X = "android:dialogLocationX";
    private static final String SAVED_DIALOG_LOCATION_Y = "android:dialogLocationY";
    private static final String SAVED_DIALOG_AMOUNT = "android:dialogAmount";
    private static final String SAVED_DIALOG_IS_NO_TITLE = "android:isNoTitle";
    private static final String SAVED_DIALOG_ANIMATIONS = "android:dialogAnimations";

    @IntDef({FLAG_FULL_DEFAULT, FLAG_FULL_HIDE_BAR, FLAG_FULL_HIDE_STATUS_BAR, FLAG_FULL_SHOW_STATUS_BAR})
    @Retention(RetentionPolicy.SOURCE)
    public @interface State {
    }

    /**
     * 默认状态
     */
    public static final int FLAG_FULL_DEFAULT = 0;

    /**
     * 隐藏状态栏、导航栏
     */
    public static final int FLAG_FULL_HIDE_BAR = 1;
    /**
     * 全屏并隐藏状态栏
     */
    public static final int FLAG_FULL_HIDE_STATUS_BAR = 2;
    /**
     * 全屏显示状态栏、导航栏
     */
    public static final int FLAG_FULL_SHOW_STATUS_BAR = 3;

    private int mState = FLAG_FULL_DEFAULT;
    /**
     * 点击空白或返回按钮是否能够取消，默认可以取消
     */
    private boolean mCancelable = true;
    /**
     * 点击空白是否能够取消，默认点击阴影不可以取消
     */
    private boolean mCancelableOnTouchOutside = false;
    /**
     * 弹框宽度、高度
     */
    private int mWidth = -10, mHeight = -10;
    /**
     * 位置
     */
    protected int mGravity = 0;
    /**
     * 弹框x、y坐标
     */
    protected float x = 0, y = 0;
    /**
     * 遮罩透明度
     */
    protected float mAmount = -1;
    /**
     * 标题是否显示
     */
    protected boolean mIsNoTitle = false;
    /**
     * style动画
     */
    protected int mAnimation = 0;
    /**
     * 弹框关闭监听
     */
    private DialogInterface.OnDismissListener mOnDismissListener;
    /**
     * dialog Key监听
     */
    private DialogInterface.OnKeyListener mOnKeyListener;

    @Override
    public final void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        onBindViewHolder(savedInstanceState, new ViewHolder(view));
    }

    @NonNull
    @Override
    public LayoutInflater onGetLayoutInflater(@Nullable Bundle savedInstanceState) {
        LayoutInflater layoutInflater = super.onGetLayoutInflater(savedInstanceState);
        return layoutInflater;
    }

    @Override
    public final void onActivityCreated(@Nullable Bundle savedInstanceState) {
        if (getShowsDialog()) {
            setShowsDialog(false);
        }
        super.onActivityCreated(savedInstanceState);
        setShowsDialog(true);
        Dialog dialog = getDialog();
        if (dialog == null) {
            return;
        }
        boolean noTitle = getNoTitle();
        int state = getState();
        if (noTitle || state == FLAG_FULL_HIDE_BAR || state == FLAG_FULL_HIDE_STATUS_BAR || state == FLAG_FULL_SHOW_STATUS_BAR) {
            dialog.requestWindowFeature(STYLE_NO_TITLE);
        }
        View view = getView();
        if (view != null) {
            if (view.getParent() != null) {
                throw new IllegalStateException(
                        "DialogFragment can not be attached to a container view");
            }
            dialog.setContentView(view);
        }
        DialogInterface.OnKeyListener onKeyListener = getOnKeyListener();
        if (onKeyListener != null) {
            dialog.setOnKeyListener(onKeyListener);
        }
        final Activity activity = getActivity();
        if (activity != null) {
            dialog.setOwnerActivity(activity);
        }
        dialog.setCancelable(getCancelEnable());
        dialog.setCanceledOnTouchOutside(getCancelableOnTouchOutside());
        dialog.setOnDismissListener(new OnDialogDismissListener());
        if (savedInstanceState != null) {
            Bundle dialogState = savedInstanceState.getBundle(SAVED_DIALOG_STATE_TAG);
            if (dialogState != null) {
                dialog.onRestoreInstanceState(dialogState);
            }
        }
        Window window = dialog.getWindow();
        Context context = getContext();
        if (window == null || context == null) {
            return;
        }
        if (state == FLAG_FULL_HIDE_BAR || state == FLAG_FULL_HIDE_STATUS_BAR) {
            //设置背景为透明
            window.setBackgroundDrawable(ContextCompat.getDrawable(context, android.R.color.transparent));
            //设置弹窗大小为全屏
            window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                    // android 11.0以上，包含11.0
                    View decorView = window.getDecorView();
                    WindowInsetsController windowInsetsController = decorView.getWindowInsetsController();
                    if (windowInsetsController != null) {
                        windowInsetsController.hide(WindowInsets.Type.statusBars());
                        if (state == FLAG_FULL_HIDE_BAR) {
                            windowInsetsController.hide(WindowInsets.Type.navigationBars());
                        }
                    }
                    // 异形屏延伸显示区域
                    WindowManager.LayoutParams params = window.getAttributes();
                    params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
                    window.setAttributes(params);
                } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    // android 5.0以上，11.0以下
                    int flag = View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
                    if (state == FLAG_FULL_HIDE_BAR) {
                        flag |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.INVISIBLE;
                    } else {
                        flag |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.INVISIBLE;
                    }
                    flag |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                        // android 9.0以上，11.0以下，包含9.0，不包含11.0
                        window.getDecorView().setSystemUiVisibility(flag);
                        // 异形屏延伸显示区域
                        WindowManager.LayoutParams params = window.getAttributes();
                        params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
                        window.setAttributes(params);
                    } else {
                        // android 5.0以上，9.0以下，包含5.0，不包含9.0
                        window.getDecorView().setSystemUiVisibility(flag);
                    }
                } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                    if (state == FLAG_FULL_HIDE_BAR) {
                        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
                    }
                }
            }
        } else if (state == FLAG_FULL_SHOW_STATUS_BAR) {
            //设置背景为透明
            window.setBackgroundDrawable(ContextCompat.getDrawable(context, android.R.color.transparent));
            // 获取应用区域大小
            Rect outRect = new Rect();
            window.getDecorView().getWindowVisibleDisplayFrame(outRect);
            int dialogHeight = outRect.height();
            //设置弹窗大小为全屏
            window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, dialogHeight == 0 ? ViewGroup.LayoutParams.MATCH_PARENT : dialogHeight);
        } else {
            int width = getWidth();
            int height = getHeight();
            if (width == ViewGroup.LayoutParams.MATCH_PARENT || height == ViewGroup.LayoutParams.MATCH_PARENT) {
                //设置背景为透明
                window.setBackgroundDrawable(ContextCompat.getDrawable(context, android.R.color.transparent));
            }
            int gravity = getGravity();
            if (gravity != 0) {
                window.setGravity(gravity);
            }
            WindowManager.LayoutParams params = window.getAttributes();
            if (height != -10) {
                params.height = height;
            }
            if (width != -10) {
                params.width = width;
            }
            float x = getX();
            if (x != 0) {
                params.x = (int) x;
            }
            float y = getY();
            if (y != 0) {
                params.y = (int) y;
            }
            window.setAttributes(params);
        }
        // 设置动画
        int animation = getAnimation();
        if (animation != 0) {
            window.setWindowAnimations(animation);
        }
        // 设置遮罩透明度
        float amount = getDimAmount();
        if (amount != -1) {
            window.setDimAmount(amount);
        }
        onActivityCreated();
    }

    @Nullable
    @Override
    public final View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        int layoutId = getLayoutId();
        if (layoutId != 0) {
            return onCreateView(inflater, container, layoutId);
        }
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        return new CustomDialog(requireContext(), getTheme());
    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        if (mState != 0) {
            outState.putInt(SAVED_DIALOG_STATE, mState);
        }
        if (!mCancelable) {
            outState.putBoolean(SAVED_CANCELABLE, mCancelable);
        }
        if (mCancelableOnTouchOutside) {
            outState.putBoolean(SAVED_CANCELABLE_OUTSIDE, mCancelableOnTouchOutside);
        }
        if (mWidth != -10) {
            outState.putInt(SAVED_DIALOG_WIDTH, mWidth);
        }
        if (mHeight != -10) {
            outState.putInt(SAVED_DIALOG_HEIGHT, mHeight);
        }
        if (mGravity != 0) {
            outState.putInt(SAVED_DIALOG_GRAVITY, mGravity);
        }
        if (x != 0) {
            outState.putFloat(SAVED_DIALOG_LOCATION_X, x);
        }
        if (y != 0) {
            outState.putFloat(SAVED_DIALOG_LOCATION_Y, y);
        }
        if (mAmount != -1) {
            outState.putFloat(SAVED_DIALOG_AMOUNT, mAmount);
        }
        if (mIsNoTitle) {
            outState.putBoolean(SAVED_DIALOG_IS_NO_TITLE, mIsNoTitle);
        }
        if (mAnimation != 0) {
            outState.putInt(SAVED_DIALOG_ANIMATIONS, mAnimation);
        }
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState != null) {
            mState = savedInstanceState.getInt(SAVED_DIALOG_STATE, FLAG_FULL_DEFAULT);
            mCancelable = savedInstanceState.getBoolean(SAVED_CANCELABLE, true);
            mCancelableOnTouchOutside = savedInstanceState.getBoolean(SAVED_CANCELABLE_OUTSIDE, false);
            mWidth = savedInstanceState.getInt(SAVED_DIALOG_WIDTH, -10);
            mHeight = savedInstanceState.getInt(SAVED_DIALOG_HEIGHT, -10);
            mGravity = savedInstanceState.getInt(SAVED_DIALOG_GRAVITY, 0);
            x = savedInstanceState.getFloat(SAVED_DIALOG_LOCATION_X, 0);
            y = savedInstanceState.getFloat(SAVED_DIALOG_LOCATION_Y, 0);
            mAmount = savedInstanceState.getFloat(SAVED_DIALOG_AMOUNT, -1);
            mIsNoTitle = savedInstanceState.getBoolean(SAVED_DIALOG_IS_NO_TITLE, false);
            mAnimation = savedInstanceState.getInt(SAVED_DIALOG_ANIMATIONS, 0);
        }
    }

    @Override
    public void onDismiss(@NonNull DialogInterface dialog) {
        super.onDismiss(dialog);
        if (mOnDismissListener != null) {
            mOnDismissListener.onDismiss(dialog);
        }
    }

    /**
     * 点击空白或返回按钮是否能够取消，默认(true)可以取消
     *
     * @param cancelable
     */
    @Override
    public void setCancelable(boolean cancelable) {
        mCancelable = cancelable;
        super.setCancelable(mCancelable);
    }

    /**
     * 把dip转为px
     *
     * @param dip
     * @return
     */
    protected float dip2px(float dip) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, getResources().getDisplayMetrics());
    }

    /**
     * 显示弹窗
     *
     * @param manager
     */
    public void show(FragmentManager manager) {
        show(manager, getClass().getSimpleName());
    }

    /**
     * 显示弹窗
     *
     * @param manager
     * @param tag
     */
    public void showAllowingStateLoss(@NonNull FragmentManager manager, @Nullable String tag) {
        try {
            Class<?> clazz = Class.forName("androidx.fragment.app.DialogFragment");
            Field dismissedField = clazz.getDeclaredField("mDismissed");
            dismissedField.setAccessible(true);
            dismissedField.set(this, false);
            Field shownByMeField = clazz.getDeclaredField("mShownByMe");
            shownByMeField.setAccessible(true);
            shownByMeField.set(this, true);
            manager.beginTransaction()
                    .add(this, tag)
                    .commitNowAllowingStateLoss();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 显示弹窗
     *
     * @param manager
     */
    public void showAllowingStateLoss(FragmentManager manager) {
        showAllowingStateLoss(manager, getClass().getSimpleName());
    }

    /**
     * 关闭弹窗
     */
    @Override
    public void dismiss() {
        dismissAllowingStateLoss();
    }

    /**
     * 创建view
     *
     * @return
     */
    protected View onCreateView(LayoutInflater inflater, ViewGroup container, int layoutId) {
        return inflater.inflate(layoutId, container, false);
    }

    /**
     * 获取布局id
     *
     * @return
     */
    protected abstract int getLayoutId();

    /**
     * 绑定数据
     *
     * @param savedInstanceState
     * @param holder
     */
    protected abstract void onBindViewHolder(Bundle savedInstanceState, ViewHolder holder);

    /**
     * onActivityCreated 回调
     */
    protected void onActivityCreated() {
    }

    /**
     * 获取状态
     */
    @State
    protected int getState() {
        return mState;
    }

    /**
     * 设置状态
     *
     * @param state
     * @return
     */
    public DialogFragment setState(@State int state) {
        this.mState = state;
        return this;
    }

    /**
     * 获取是否有标题
     *
     * @return true：没有标题，false：有标题
     */
    protected boolean getNoTitle() {
        return mIsNoTitle;
    }

    /**
     * 设置是否有标题
     *
     * @param isNoTitle true：没有标题，false：有标题
     * @return
     */
    public DialogFragment setNoTitle(boolean isNoTitle) {
        this.mIsNoTitle = isNoTitle;
        return this;
    }

    /**
     * 获取x坐标
     */
    protected float getX() {
        return x;
    }

    /**
     * 获取y坐标
     */
    protected float getY() {
        return y;
    }

    /**
     * 设置x,y坐标
     *
     * @param x
     * @param y
     * @return
     */
    public DialogFragment setXY(float x, float y) {
        this.x = x;
        this.y = y;
        return this;
    }

    /**
     * 获取宽度
     *
     * @return
     */
    protected int getWidth() {
        return mWidth;
    }

    /**
     * 获取高度
     *
     * @return
     */
    protected int getHeight() {
        return mHeight;
    }

    /**
     * 宽度充满
     *
     * @return
     */
    public DialogFragment fullWidth() {
        mWidth = ViewGroup.LayoutParams.MATCH_PARENT;
        return this;
    }

    /**
     * 高度充满
     *
     * @return
     */
    public DialogFragment fullHeight() {
        mHeight = ViewGroup.LayoutParams.MATCH_PARENT;
        return this;
    }

    /**
     * 充满整个屏幕
     *
     * @return
     */
    public DialogFragment full() {
        mWidth = ViewGroup.LayoutParams.MATCH_PARENT;
        mHeight = ViewGroup.LayoutParams.MATCH_PARENT;
        return this;
    }

    /**
     * 获取位置
     *
     * @return
     */
    protected int getGravity() {
        return mGravity;
    }

    /**
     * 设置位置
     *
     * @param gravity
     * @return
     */
    public DialogFragment setGravity(int gravity) {
        mGravity = gravity;
        return this;
    }

    /**
     * 设置dialog的宽度
     *
     * @param width px
     * @return
     */
    public DialogFragment setWidth(int width) {
        mWidth = width;
        return this;
    }

    /**
     * 设置dialog的宽度
     *
     * @param width dp
     * @return
     */
    public DialogFragment setWidth(float width) {
        return setWidth((int) dip2px(width));
    }

    /**
     * 设置dialog的高度
     *
     * @param height px
     * @return
     */
    public DialogFragment setHeight(int height) {
        mHeight = height;
        return this;
    }

    /**
     * 设置dialog的高度
     *
     * @param height dp
     * @return
     */
    public DialogFragment setHeight(float height) {
        return setHeight((int) dip2px(height));
    }

    /**
     * 点击空白或返回按钮是否能够取消，默认(true)可以取消
     *
     * @return true 可以取消，false 不可以取消
     */
    protected boolean getCancelEnable() {
        return mCancelable;
    }

    /**
     * 点击空白或返回按钮是否能够取消，默认(true)可以取消
     *
     * @param cancelable
     */
    public DialogFragment setCancelEnable(boolean cancelable) {
        mCancelable = cancelable;
        return this;
    }

    /**
     * 点击空白是否能够取消，默认(false)点击阴影不可以取消
     *
     * @return true 可以取消，false 不可以取消
     */
    protected boolean getCancelableOnTouchOutside() {
        return mCancelableOnTouchOutside;
    }

    /**
     * 点击空白是否能够取消，默认(false)点击阴影不可以取消
     * Sets whether the dialog is cancelable or not.  Default is true.
     *
     * @return This Builder object to allow for chaining of calls to set methods
     */
    public DialogFragment setCancelableOnTouchOutside(boolean cancelableOnTouchOutside) {
        mCancelableOnTouchOutside = cancelableOnTouchOutside;
        return this;
    }

    /**
     * 获取遮罩透明度
     *
     * @return
     */
    protected float getDimAmount() {
        return mAmount;
    }

    /**
     * 设置遮罩透明度
     *
     * @param amount
     * @return
     */
    public DialogFragment setDimAmount(float amount) {
        this.mAmount = amount;
        return this;
    }

    /**
     * 获取动画
     *
     * @return
     */
    protected int getAnimation() {
        return mAnimation;
    }

    /**
     * 从底部弹出
     *
     * @param isAnimation 是否有动画
     * @return
     */
    public DialogFragment formBottom(boolean isAnimation) {
        if (isAnimation) {
            mAnimation = R.style.dialog_from_bottom_anim;
        }
        mGravity = Gravity.BOTTOM;
        return this;
    }

    /**
     * 添加默认动画
     *
     * @return
     */
    public DialogFragment addDefaultAnimation() {
        mAnimation = R.style.dialog_default_anim;
        return this;
    }

    /**
     * 设置动画
     *
     * @param styleAnimation
     * @return
     */
    public DialogFragment setAnimation(int styleAnimation) {
        mAnimation = styleAnimation;
        return this;
    }

    /**
     * dialog Dismiss监听
     * Sets the callback that will be called when the dialog is dismissed for any reason.
     *
     * @return This Builder object to allow for chaining of calls to set methods
     */
    public DialogFragment setOnDismissListener(DialogInterface.OnDismissListener listener) {
        mOnDismissListener = listener;
        return this;
    }

    /**
     * 获取dialog Key监听
     *
     * @return
     */
    protected DialogInterface.OnKeyListener getOnKeyListener() {
        return mOnKeyListener;
    }

    /**
     * dialog Key监听
     * Sets the callback that will be called if a key is dispatched to the dialog.
     *
     * @return This Builder object to allow for chaining of calls to set methods
     */
    public DialogFragment setOnKeyListener(DialogInterface.OnKeyListener listener) {
        this.mOnKeyListener = listener;
        return this;
    }

    /**
     * 解决屏幕旋转后 状态无法保持
     * 在activity或fragment onCreate()方法中调用
     * 如果返回不为null，重新设置监听或数据
     *
     * @param savedInstanceState
     * @param manager
     * @param tag
     * @param <T>
     * @return
     */
    public static <T extends androidx.fragment.app.DialogFragment> T getDialogFragment(Bundle savedInstanceState, FragmentManager manager, String tag) {
        if (savedInstanceState != null) {
            return (T) manager.findFragmentByTag(tag);
        }
        return null;
    }

    public class ViewHolder {

        private View mView;

        /**
         * 防止oom
         */
        private SparseArray<WeakReference<View>> mViews;

        ViewHolder(View view) {
            mViews = new SparseArray<>();
            mView = view;
        }

        /**
         * 减少findViewById的次数
         *
         * @param viewId
         * @param <T>
         * @return
         */
        @SuppressWarnings("unchecked")
        public <T extends View> T getView(@IdRes int viewId) {
            WeakReference<View> viewReference = mViews.get(viewId);
            View view = null;
            if (viewReference != null) {
                view = viewReference.get();
            }
            if (view == null) {
                view = mView.findViewById(viewId);
                if (view != null) {
                    mViews.put(viewId, new WeakReference<>(view));
                }
            }
            return (T) view;
        }

        /**
         * 设置padding
         *
         * @param viewId
         * @param left   dp
         * @param top    dp
         * @param right  dp
         * @param bottom dp
         * @return
         */
        public ViewHolder setPadding(@IdRes int viewId, float left, float top, float right, float bottom) {
            return setPadding(viewId, (int) dip2px(left), (int) dip2px(top), (int) dip2px(right), (int) dip2px(bottom));
        }

        /**
         * 设置padding
         *
         * @param viewId
         * @param left   px
         * @param top    px
         * @param right  px
         * @param bottom px
         * @return
         */
        public ViewHolder setPadding(@IdRes int viewId, @Px int left, @Px int top, @Px int right, @Px int bottom) {
            View view = getView(viewId);
            if (view != null) {
                view.setPadding(left, top, right, bottom);
            }
            return this;
        }

        /**
         * 设置padding
         *
         * @param viewId
         * @param padding
         * @return
         */
        public ViewHolder setPadding(@IdRes int viewId, @Px int padding) {
            return setPadding(viewId, padding, padding, padding, padding);
        }

        /**
         * 设置背景
         *
         * @param viewId
         * @param background
         * @return
         */
        public ViewHolder setBackground(@IdRes int viewId, Drawable background) {
            View view = getView(viewId);
            if (view != null) {
                view.setBackground(background);
            }
            return this;
        }

        /**
         * 设置背景资源
         *
         * @param viewId
         * @param resid
         * @return
         */
        public ViewHolder setBackgroundResource(@IdRes int viewId, @DrawableRes int resid) {
            View view = getView(viewId);
            if (view != null) {
                view.setBackgroundResource(resid);
            }
            return this;
        }

        /**
         * 设置背景颜色
         *
         * @param viewId
         * @param color
         * @return
         */
        public ViewHolder setBackgroundColorInt(@IdRes int viewId, @ColorInt int color) {
            View view = getView(viewId);
            if (view != null) {
                view.setBackgroundColor(color);
            }
            return this;
        }

        /**
         * 设置背景颜色
         *
         * @param viewId
         * @param colorRes
         * @return
         */
        public ViewHolder setBackgroundColor(@IdRes int viewId, @ColorRes int colorRes) {
            View view = getView(viewId);
            if (view != null) {
                view.setBackgroundColor(ContextCompat.getColor(view.getContext(), colorRes));
            }
            return this;
        }

        /**
         * 设置背景颜色
         *
         * @param viewId
         * @param colorString
         * @return
         */
        public ViewHolder setBackgroundColor(@IdRes int viewId, String colorString) {
            return setBackgroundColorInt(viewId, Color.parseColor(colorString));
        }

        /**
         * 设置alpha
         *
         * @param viewId
         * @param alpha
         * @return
         */
        public ViewHolder setAlpha(@IdRes int viewId, int alpha) {
            View view = getView(viewId);
            if (view != null) {
                view.setAlpha(alpha);
            }
            return this;
        }

        /**
         * 设置Visibility
         *
         * @param viewId
         * @param visibility
         * @return
         */
        public ViewHolder setVisibility(@IdRes int viewId, int visibility) {
            View view = getView(viewId);
            if (view != null) {
                view.setVisibility(visibility);
            }
            return this;
        }

        /**
         * 设置Visible
         *
         * @param viewId
         * @param visible
         * @return
         */
        public ViewHolder setVisible(@IdRes int viewId, boolean visible) {
            View view = getView(viewId);
            if (view != null) {
                if (visible) {
                    view.setVisibility(View.VISIBLE);
                } else {
                    view.setVisibility(View.GONE);
                }
            }
            return this;
        }

        /**
         * 获取Visible
         *
         * @param viewId
         * @return
         */
        public boolean getVisible(@IdRes int viewId) {
            View view = getView(viewId);
            if (view != null) {
                return view.getVisibility() == View.VISIBLE;
            }
            return false;
        }

        /**
         * 获取Visibility
         *
         * @param viewId
         * @return
         */
        public int getVisibility(@IdRes int viewId) {
            View view = getView(viewId);
            if (view != null) {
                return view.getVisibility();
            }
            return View.GONE;
        }

        /**
         * 设置TextView文本
         *
         * @param viewId
         * @param text
         * @return
         */
        public ViewHolder setText(@IdRes int viewId, CharSequence text) {
            TextView tv = getView(viewId);
            if (tv != null) {
                tv.setText(text);
            }
            return this;
        }

        /**
         * 设置TextView文本
         *
         * @param viewId
         * @param resid
         * @return
         */
        public ViewHolder setText(@IdRes int viewId, @StringRes int resid) {
            TextView tv = getView(viewId);
            if (tv != null) {
                tv.setText(resid);
            }
            return this;
        }

        /**
         * 设置TextView文本
         *
         * @param viewId
         * @param value
         * @return
         */
        public ViewHolder setTextInt(@IdRes int viewId, int value) {
            return setText(viewId, String.valueOf(value));
        }

        /**
         * 设置TextView文本
         *
         * @param viewId
         * @param value
         * @return
         */
        public ViewHolder setText(@IdRes int viewId, float value) {
            return setText(viewId, String.valueOf(value));
        }

        /**
         * 设置TextView文本
         *
         * @param viewId
         * @param value
         * @return
         */
        public ViewHolder setText(@IdRes int viewId, double value) {
            return setText(viewId, String.valueOf(value));
        }

        /**
         * 设置TextView文本
         *
         * @param viewId
         * @param value
         * @return
         */
        public ViewHolder setText(@IdRes int viewId, long value) {
            return setText(viewId, String.valueOf(value));
        }

        /**
         * 设置文字大小
         *
         * @param viewId
         * @param textSize sp
         */
        public ViewHolder setTextSize(@IdRes int viewId, float textSize) {
            TextView tv = getView(viewId);
            if (tv != null) {
                tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);
            }
            return this;
        }

        /**
         * 设置文字颜色
         *
         * @param viewId
         * @param color
         */
        public ViewHolder setTextColorInt(@IdRes int viewId, @ColorInt int color) {
            TextView tv = getView(viewId);
            if (tv != null) {
                tv.setTextColor(color);
            }
            return this;
        }

        /**
         * 设置文字颜色
         *
         * @param viewId
         * @param colorRes
         */
        public ViewHolder setTextColor(@IdRes int viewId, @ColorRes int colorRes) {
            TextView tv = getView(viewId);
            if (tv != null) {
                tv.setTextColor(ContextCompat.getColor(tv.getContext(), colorRes));
            }
            return this;
        }

        /**
         * 设置文字颜色
         *
         * @param viewId
         * @param colorString
         */
        public ViewHolder setTextColor(@IdRes int viewId, String colorString) {
            return setTextColorInt(viewId, Color.parseColor(colorString));
        }

        /**
         * 设置TextView提示
         *
         * @param viewId
         * @param text
         * @return
         */
        public ViewHolder setHint(@IdRes int viewId, CharSequence text) {
            TextView tv = getView(viewId);
            if (tv != null) {
                tv.setHint(text);
            }
            return this;
        }

        /**
         * 设置TextView提示
         *
         * @param viewId
         * @param resid
         * @return
         */
        public ViewHolder setHint(@IdRes int viewId, @StringRes int resid) {
            TextView tv = getView(viewId);
            if (tv != null) {
                tv.setHint(resid);
            }
            return this;
        }

        /**
         * 设置TextView提示
         *
         * @param viewId
         * @param value
         * @return
         */
        public ViewHolder setHintInt(@IdRes int viewId, int value) {
            return setHint(viewId, String.valueOf(value));
        }

        /**
         * 设置TextView提示
         *
         * @param viewId
         * @param value
         * @return
         */
        public ViewHolder setHint(@IdRes int viewId, float value) {
            return setHint(viewId, String.valueOf(value));
        }

        /**
         * 设置TextView提示
         *
         * @param viewId
         * @param value
         * @return
         */
        public ViewHolder setHint(@IdRes int viewId, double value) {
            return setHint(viewId, String.valueOf(value));
        }

        /**
         * 设置TextView提示
         *
         * @param viewId
         * @param value
         * @return
         */
        public ViewHolder setHint(@IdRes int viewId, long value) {
            return setHint(viewId, String.valueOf(value));
        }

        /**
         * 设置提示字体颜色
         *
         * @param viewId
         * @param color
         */
        public ViewHolder setHintTextColorInt(@IdRes int viewId, @ColorInt int color) {
            TextView tv = getView(viewId);
            if (tv != null) {
                tv.setHintTextColor(color);
            }
            return this;
        }

        /**
         * 设置提示字体颜色
         *
         * @param viewId
         * @param colorRes
         */
        public ViewHolder setHintTextColor(@IdRes int viewId, @ColorRes int colorRes) {
            TextView tv = getView(viewId);
            if (tv != null) {
                tv.setHintTextColor(ContextCompat.getColor(tv.getContext(), colorRes));
            }
            return this;
        }

        /**
         * 设置提示字体颜色
         *
         * @param viewId
         * @param colorString
         */
        public ViewHolder setHintTextColor(@IdRes int viewId, String colorString) {
            return setHintTextColorInt(viewId, Color.parseColor(colorString));
        }

        /**
         * 设置ImageView显示模式
         *
         * @param viewId
         * @param scaleType
         * @return
         */
        public ViewHolder setScaleType(@IdRes int viewId, ImageView.ScaleType scaleType) {
            ImageView iv = getView(viewId);
            if (iv != null) {
                iv.setScaleType(scaleType);
            }
            return this;
        }

        /**
         * 设置ImageView的图片透明
         *
         * @param viewId
         * @param alpha
         * @return
         */
        public ViewHolder setImageAlpha(@IdRes int viewId, int alpha) {
            ImageView iv = getView(viewId);
            if (iv != null) {
                iv.setImageAlpha(alpha);
            }
            return this;
        }

        /**
         * 设置ImageView的图片
         *
         * @param viewId
         * @param bitmap
         * @return
         */
        public ViewHolder setImageBitmap(@IdRes int viewId, Bitmap bitmap) {
            ImageView iv = getView(viewId);
            if (iv != null) {
                iv.setImageBitmap(bitmap);
            }
            return this;
        }

        /**
         * 设置ImageView的图片
         *
         * @param viewId
         * @param icon
         * @return
         */
        public ViewHolder setImageDrawable(@IdRes int viewId, Icon icon) {
            ImageView iv = getView(viewId);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (iv != null) {
                    iv.setImageIcon(icon);
                }
            }
            return this;
        }

        /**
         * 设置ImageView的图片
         *
         * @param viewId
         * @param drawable
         * @return
         */
        public ViewHolder setImageDrawable(@IdRes int viewId, Drawable drawable) {
            ImageView iv = getView(viewId);
            if (iv != null) {
                iv.setImageDrawable(drawable);
            }
            return this;
        }

        /**
         * 设置ImageView的资源
         *
         * @param viewId
         * @param resourceId
         * @return
         */
        public ViewHolder setImageResource(@IdRes int viewId, @DrawableRes int resourceId) {
            ImageView iv = getView(viewId);
            if (iv != null) {
                iv.setImageResource(resourceId);
            }
            return this;
        }

        /**
         * 设置View的点击事件
         *
         * @param viewId
         * @param listener
         * @return
         */
        public ViewHolder setOnClickListener(@IdRes int viewId, View.OnClickListener listener) {
            View view = getView(viewId);
            if (view != null) {
                view.setOnClickListener(listener);
            }
            return this;
        }

        /**
         * 设置View的长按事件
         *
         * @param viewId
         * @param listener
         * @return
         */
        public ViewHolder setOnLongClickListener(@IdRes int viewId, View.OnLongClickListener listener) {
            View view = getView(viewId);
            if (view != null) {
                view.setOnLongClickListener(listener);
            }
            return this;
        }
    }

    private class CustomDialog extends Dialog {

        public CustomDialog(@NonNull Context context, int themeResId) {
            super(context, themeResId);
        }

        @Override
        public void setOnDismissListener(@Nullable OnDismissListener listener) {
            if (listener instanceof OnDialogDismissListener) {
                super.setOnDismissListener(listener);
            } else if (listener != null) {
                super.setOnDismissListener(new OnDialogDismissListener());
            } else {
                super.setOnDismissListener(null);
            }
        }
    }

    class OnDialogDismissListener implements DialogInterface.OnDismissListener {
        @Override
        public void onDismiss(DialogInterface dialog) {
            DialogFragment.this.onDismiss(dialog);
        }
    }
}
